﻿// testddp.cpp : Defines the entry point for the console application.
//

// opencvhello3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"


#define ROWNUM 8
#define COLNUM 8
#define MAX_WIDTH 8
#define MAX_HIGH 8
#define MAX_WIDTH_EX 8
#define MAX_HIGH_EX 8
#define SLEEPTIME 10 // 点击间隔
#define INITX 266
#define INITY 60
#define GRIDSIZE 64
#define POSX 24
#define POSY 24
//343 414-40 renren
//#define PAUSE
int b[MAX_WIDTH][MAX_HIGH]; //图片矩阵，0为空白，从11开始表示不同图片
int map[MAX_WIDTH_EX][MAX_HIGH_EX]; //图片矩阵 + 一圈0（方便外围连接）
char * filename = "ddp.bmp";

FILE *fpsol=fopen("sol.txt","w+");
/*
typedef struct tagPOINT {
int x;
int y;
} POINT;*/

int Find(int aMap[MAX_WIDTH_EX][MAX_HIGH_EX]);
//测试是否结束
bool testEmpty(int aMap[MAX_WIDTH_EX][MAX_HIGH_EX]);
//测试两个点是不是能一条线连接
bool testLine(int aMap[MAX_WIDTH_EX][MAX_HIGH_EX],POINT *ap1,POINT* ap2);
//测试一个折线
bool testcorner(int aMap[MAX_WIDTH_EX][MAX_HIGH_EX],POINT *ap1,POINT* ap2);
//测试两个折线
bool testtwocorner(int aMap[MAX_WIDTH_EX][MAX_HIGH_EX],POINT *ap1,POINT* ap2);
//根据图片，生成图片矩阵
void gen_map();
//根据关卡，移动图片矩阵元素
void move_map(int map[MAX_WIDTH_EX][MAX_HIGH_EX]);
//截图，保存成文件，问题：速度慢，用到MFC? afxwin.h?
void screen(char filename[])
{ 
	CDC *pdc; 
	pdc=CDC::FromHandle(GetDC(NULL)); 
	int BitPerPixel=pdc->GetDeviceCaps(BITSPIXEL); 
	int width=pdc->GetDeviceCaps(HORZRES); 
	int height=pdc->GetDeviceCaps(VERTRES); 
	//cout<<"当前屏幕色彩模式为"<<BitPerPixel<<"位色彩"<<endl 
	//	<<"屏幕宽度:"<<width<<endl 
	//	<<"屏幕高度:"<<height<<endl<<endl; 

	CDC memdc; 
	memdc.CreateCompatibleDC(pdc); 

	CBitmap memBitmap, *oldmembitmap; 
	memBitmap.CreateCompatibleBitmap(pdc,width,height); 

	oldmembitmap=memdc.SelectObject(&memBitmap); 
	memdc.BitBlt(0,0,width,height,pdc,0,0,SRCCOPY); 

	BITMAP bmp; 
	memBitmap.GetBitmap(&bmp); 

	FILE *fp=fopen(filename,"wb"); 

	BITMAPINFOHEADER bih={0}; 
	bih.biBitCount=bmp.bmBitsPixel; 
	bih.biCompression=BI_RGB; 
	bih.biHeight=bmp.bmHeight; 
	bih.biPlanes=1; 
	bih.biSize=sizeof(BITMAPINFOHEADER); 
	bih.biSizeImage=bmp.bmWidthBytes*bmp.bmHeight; 
	bih.biWidth=bmp.bmWidth; 

	BITMAPFILEHEADER bfh={0}; 
	bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); 
	bfh.bfSize=bfh.bfOffBits+bmp.bmWidthBytes*bmp.bmHeight; 
	bfh.bfType=(WORD)0x4d42; 

	fwrite(&bfh,1,sizeof(BITMAPFILEHEADER),fp); 
	fwrite(&bih,1,sizeof(BITMAPINFOHEADER),fp); 
	byte *p=new byte[bmp.bmWidthBytes*bmp.bmHeight]; 
	GetDIBits(memdc.m_hDC,(HBITMAP)memBitmap.m_hObject,0,height,p,(LPBITMAPINFO) &bih,DIB_RGB_COLORS); 

	fwrite(p,1,bmp.bmWidthBytes*bmp.bmHeight,fp); 

	delete []p; 
	fclose(fp); 
	memdc.SelectObject(oldmembitmap); 
}
void Click(int x, int y)
{
	POINT p;
	p.x=x;
	p.y=y;
	HWND hWnd=WindowFromPoint(p);
	if (ScreenToClient(hWnd, &p))
	{
		PostMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(p.x, p.y));
		PostMessage(hWnd, WM_LBUTTONUP, 0, MAKELONG(p.x, p.y));
	}
}

void click2points(int x,int y,int x1,int y1){
	/*
	HWND hwndCalc;

	hwndCalc = FindWindow( "Bejeweled Blitz v1.0.6.4034",NULL);

	if(!hwndCalc){
		printf("can't find window\n") ;
	}else{
		SendMessage(hwndCalc, WM_LBUTTONDOWN,0, MAKEWPARAM(((x)*GRIDSIZE+253+48), (y)*60+62+48)));
		Sleep(SLEEPTIME);
		SendMessage(hwndCalc, WM_LBUTTONUP,0, MAKEWPARAM(((x)*60+253+48), (y)*60+62+48)));
		Sleep(SLEEPTIME);
	}
	*/
	Click(((x)*GRIDSIZE+INITX+48),(y)*GRIDSIZE+INITY+48);
	Click(((x1)*GRIDSIZE+INITX+48),(y1)*GRIDSIZE+INITY+48);
	Sleep(SLEEPTIME);

	/*
	Sleep(SLEEPTIME);
	mouse_event((int)(MOUSEEVENTF_LEFTUP|MOUSEEVENTF_ABSOLUTE), (65535/1280)*((x)*60+253+48), (65535/800)*((y)*60+62+48), 0, 0);
	Sleep(SLEEPTIME);
	mouse_event((int)(MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE), (65535/1280)*((x1)*60+253+48), (65535/800)*((y1)*60+62+48), 0, 0);
	Sleep(SLEEPTIME);
	mouse_event((int)(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_ABSOLUTE), (65535/1280)*((x1)*60+253+48), (65535/800)*((y1)*60+62+48), 0, 0);
	Sleep(SLEEPTIME);
	mouse_event((int)(MOUSEEVENTF_LEFTUP|MOUSEEVENTF_ABSOLUTE), (65535/1280)*((x1)*60+253+48), (65535/800)*((y1)*60+62+48), 0, 0);
	Sleep(SLEEPTIME);
	*/
	fprintf(fpsol,"%d %d %d %d\n",x,y,x1,y1);
	fflush(fpsol);
	

}
int Find(int aMap[MAX_WIDTH_EX][MAX_HIGH_EX])
{
	POINT p1={0};
	POINT p2={0};
	int i,j;
	
	//screen(filename);

	
	
	
		for(i=0;i<MAX_WIDTH_EX;i++){
			for(j=0;j<MAX_HIGH_EX-1;j++){
				//其中有两个相连  图二
				if(aMap[i][j] == aMap[i][j+1]){
					//检测 1
					if(i-1>=0 && j-1>=0){
						if(aMap[i][j] == aMap[i-1][j-1]){
							//click2points(j-1,i-1,j-1,i);              
							click2points(i-1,j-1,i,j-1);    
							//return true;
						}
					}
					//检测 2
					if(i-1 >= 0 && j+2<MAX_HIGH_EX){
						if(aMap[i][j] == aMap[i-1][j+2]){
							click2points(i-1,j+2,i,j+2);   
							//return true;
						}
					}
					//检测 3
					if(j-2>=0){
						if(aMap[i][j] == aMap[i][j-2]){
							click2points(i,j-2,i,j-1);   
							//return true;
						}
					}
					//检测 4
					if(j+3<MAX_HIGH_EX){
						if(aMap[i][j] == aMap[i][j+3]){
							click2points(i,j+3,i,j+2);   
							//return true;
						}
					}
					//检测 5
					if(i+1<MAX_WIDTH_EX && j-1>=0){
						if(aMap[i][j] == aMap[i+1][j-1]){
							click2points(i+1,j-1,i,j-1);   
							//return true;
						}
					}
					//检测 6
					if(i+1<MAX_WIDTH_EX && j+2 < MAX_HIGH_EX){
						if(aMap[i][j] == aMap[i+1][j+2]){
							click2points(i+1,j+2,i,j+2);   
							//return true;
						}
					}
				}
				else{
					//两个相隔一格 图四
					if(j+2<MAX_HIGH_EX){
						if(aMap[i][j] == aMap[i][j+2]){
							//检测1
							if(i-1>=0){
								if(aMap[i][j] == aMap[i-1][j+1]){
									click2points(i-1,j+1,i,j+1);   
									//return true;   
								}
							}
							//检测2
							if(i+1<MAX_WIDTH_EX){
								if(aMap[i][j] == aMap[i+1][j+1]){
									click2points(i+1,j+1,i,j+1);   
									//return true;
								}
							}
							//检测3
							if(j-1>=0){
								if(aMap[i][j] == aMap[i][j-1]){
									click2points(i,j+2,i,j+1);   
									//return true;
								}
							}
							//检测4
							if(j+3<MAX_HIGH_EX){
								if(aMap[i][j] == aMap[i][j+3]){
									click2points(i,j,i,j+1);   
									//return true;
								}
							}
						}
					}
				}
			}
		}               
		for(i=0;i<MAX_HIGH_EX;i++){
			for(j=0;j<MAX_WIDTH_EX-1;j++){
				//如果有两个相连  图一
				if(aMap[j][i] == aMap[j+1][i]){
					//检测1
					if(j-2>=0){
						if(aMap[j][i] == aMap[j-2][i]){
							click2points(j-2,i,j-1,i);   
							//return true;
						}
					}
					//检测2
					if(j-1>=0  && i-1>=0){
						if(aMap[j][i] == aMap[j-1][i-1]){
							click2points(j-1,i-1,j-1,i);   
							//return true;
						}
					}
					//检测3
					if(j-1>=0 && i+1<MAX_HIGH_EX){
						if(aMap[j][i] == aMap[j-1][i+1]){
							click2points(j-1,i+1,j-1,i);   
							//return true;
						}
					}
					//检测4
					if(j+2<MAX_WIDTH_EX && i-1>=0){
						if(aMap[j][i] == aMap[j+2][i-1]){
							click2points(j+2,i-1,j+2,i);   
							//return true;
						}
					}
					//检测5
					if(j+2<MAX_WIDTH_EX && i+1 <MAX_HIGH_EX){
						if(aMap[j][i] == aMap[j+2][i+1]){
							click2points(j+2,i+1,j+2,i);   
							//return true;
						}
					}
					//检测6
					if(j+3<MAX_WIDTH_EX){
						if(aMap[j][i] == aMap[j+3][i]){
							click2points(j+3,i,j+2,i);   
							//return true;
						}
					}
				}
				else{
					//间隔相同  图三
					if(j+2<MAX_WIDTH_EX){
						if(aMap[j][i] == aMap[j+2][i]){
							//检测1
							if(i-1>=0){
								if(aMap[j][i] == aMap[j+1][i-1]){
									click2points(j+1,i-1,j+1,i);   
									//return true;
								}
							}
							//检测2
							if(i+1<MAX_HIGH_EX){
								if(aMap[j][i] == aMap[j+1][i+1]){
									click2points(j+1,i+1,j+1,i);   
									//return true;
								}
							}
							//检测3
							if(j-1>=0){
								if(aMap[j][i] == aMap[j-1][i]){
									click2points(j+2,i,j+1,i);   
									//return true;
								}
							}
							//检测4
							if(j+3<MAX_WIDTH_EX){
								if(aMap[j][i] == aMap[j+3][i]){
									click2points(j,i,j+1,i);   
									//return true;
								}
							}
						}
					}
				}
			}
		}
		fclose(fpsol);
	return 0;
}



void gen_map()
{
	IplImage*  pImg,* pdiff,*temp1; //声明IplImage指针
	char * filename = "ddp.bmp";
	IplImage* partImg[MAX_WIDTH][MAX_HIGH];
	//载入图像
	if( (pImg = cvLoadImage( filename, 1)) != 0 )
	{
		int i,j;
		for(i = 0; i<MAX_WIDTH;i++)
			for(j=0; j<MAX_HIGH;j++)
			{
				cvSetImageROI( pImg, cvRect(INITX+GRIDSIZE*i,INITY+GRIDSIZE*j,GRIDSIZE,GRIDSIZE ));//初始化小图片矩阵。 326,218是左上角坐标。44,40小图的宽和高 314-60=254,182-120=62
				partImg[i][j]=cvCloneImage(pImg);
				cvResetImageROI( pImg);
			}
			//cvReleaseImage(&partImg[i-1][j-1]);
			//cvSetImageROI( pImg, cvRect(254+60*(i-1),62+1+60*(j-1),60,60 )); //右下角的图下移了一个像素，so 218+1
			//partImg[i-1][j-1]=cvCloneImage(pImg);
			//cvResetImageROI( pImg);

			pdiff = cvCreateImage(cvGetSize(partImg[0][0]),partImg[0][0]->depth,partImg[0][0]->nChannels); //存差值
			temp1 = cvCreateImage(cvGetSize(partImg[0][0]),partImg[0][0]->depth,1); 
			//printf("%d %d\n",partImg[0][0]->width, partImg[0][0]->height);

			int c=10;
			int q,p;
			int a=0;
			FILE *fdiffp =fopen("fdiff.txt","w"); //writable
			for(i = 0; i<MAX_WIDTH;i++)
				for(j=0; j<MAX_HIGH;j++) 
				{
						p = i;
						if(b[i][j]==0){ //没和前面的匹配过
							c++; //id#
							b[i][j]=c;
							for(q = j+1; q<MAX_HIGH;q++) //b[i][j+1..末尾]
							{
								a = 0;
								CvScalar s,s1;
								s=cvGet2D(partImg[i][j],POSX,POSY); // get the (i,j) pixel value
								s1=cvGet2D(partImg[p][q],POSX,POSY);

								a = abs(s.val[0]-s1.val[0])+ abs(s.val[1]-s1.val[1])+ abs(s.val[2]-s1.val[2]);
								fprintf(fdiffp,"%d %d %d %d %d %d\n",i,j,p,q,a,c);
								fprintf(fdiffp,"B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
								fprintf(fdiffp,"B=%f, G=%f, R=%f\n\n",s1.val[0],s1.val[1],s1.val[2]);
								if(a<100) // matched
								{
									fprintf(fdiffp,"match!\n");
									b[p][q]=c;
								}
							}	

							for(p=i+1; p<MAX_WIDTH;p++){//b[i+1..末尾][j+1..末尾]
								for(q=0; q<MAX_HIGH;q++) 
								{
									CvScalar s,s1;
									s=cvGet2D(partImg[i][j],POSX,POSY); // get the (i,j) pixel value
									s1=cvGet2D(partImg[p][q],POSX,POSY);

									a = abs(s.val[0]-s1.val[0])+ abs(s.val[1]-s1.val[1])+ abs(s.val[2]-s1.val[2]);
									fprintf(fdiffp,"%d %d %d %d %d %d\n",i,j,p,q,a,c);
									fprintf(fdiffp,"B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
									fprintf(fdiffp,"B=%f, G=%f, R=%f\n\n",s1.val[0],s1.val[1],s1.val[2]);
									if(a<100) // matched
									{
										fprintf(fdiffp,"match!\n");
										b[p][q]=c;
									}
								}			
							}
						}//if(b[][])
				}
				FILE *fp =fopen("map.txt","w");
				if(fp !=NULL){
					for(j=0;j<MAX_HIGH;j++){
						for(i=0;i<MAX_WIDTH;i++){
							fprintf(fp,"%d ",b[i][j]);
						}
						fprintf(fp,"\n");
					}
				}
				fflush(fp);
				fclose(fp);
				for(i=0;i<MAX_WIDTH;i++) //转成外围包一层0的矩阵
					for(j=0;j<MAX_HIGH;j++){
						map[i][j]=b[i][j];
					}

					cvReleaseImage( &pImg ); //释放图像
					cvReleaseImage(&pdiff);
					cvReleaseImage(&temp1);

					for(i = 0; i<MAX_WIDTH;i++)
						for(j=0; j<MAX_HIGH;j++)
						{

							cvReleaseImage(&partImg[i][j]);

						}
	}//if
	else{
		printf("load file error\n");
		exit(0);
	}
}

void  reset(){
	int i,j;
	for(i = 0; i<MAX_WIDTH;i++)
		for(j=0; j<MAX_HIGH;j++)
		{

			b[i][j]=0;

		}

}
int main( int argc, char** argv )
{



	//IplImage* pImg;
	//printf("input level: ");
	//scanf("%d",&type);
	Sleep(3000);//延时3s
	int x=0;
	while(1){
		
		screen(filename);
		gen_map();

		
		 
		Find(map);
		reset();
		printf("%d\n",x++);
		if(x==120)
			break;
		//Sleep(1000);
	}
	/*
	while (1) {

	if(Find(map)){

	continue;
	}
	if(testEmpty(map))
	break;
	if(x>30){
	printf("无解，你运气真好！\n");
	break;
	}
	printf("new Find\n");
	x++;
	}
	*/
	return 0;

}